package com.styles.codingstyle.Security.service;

import com.styles.codingstyle.Security.mapperAndInter.UserRolesMapper;
import com.styles.codingstyle.Security.mapperAndInter.UserServiceForSecurity;
import com.styles.codingstyle.Security.pojo.UserRoles;
import com.styles.codingstyle.VO.UserVO;
import com.styles.codingstyle.dataobject.UserEntity;
import com.styles.codingstyle.enums.SECURITY_ROLES_ENUM;
import com.styles.codingstyle.exception.CommonException;
import com.styles.codingstyle.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @Package com.styles.codingstyle.Security
 * @Description: 安全模块用于验证用户合法性
 * @Author 陈建
 * @Create: 2018-06-07 11:10
 * @Version 1.0
 * @Update: message
 */
@Service
@Transactional
public class UserServiceForSecurityImpl implements UserServiceForSecurity {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRolesMapper userRolesMapper;


    /**
     * @Description: 权限认证
     * @Param: [username]
     * @Return: org.springframework.security.core.userdetails.UserDetails
     * @Author: 陈建
     * @date: 2018/6/11 17:13
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //通过用户名查找用户信息(存储用户信息的时候必须前置校验用户重名),list默认已经初始化;
        List<UserEntity> list = userMapper.findByUsername(username);

        if (null != list) {
            if (list.size() == 1) {
                //list长度为一,说明根据用户名查找到唯一一条匹配数据.此时数据正常;
                //数据正常,获取唯一用户
                UserEntity userEntity = list.get(0);
                //获取用户权限列表
                List<SimpleGrantedAuthority> simpleGrantedAuthorities = createAuthorities(userEntity.getId());
                //创建用户安全认证实体(此处user为:org.springframework.security.core.userdetails.User;)
                User user = new User(userEntity.getUsername(), userEntity.getPassword(), simpleGrantedAuthorities);
                return user;
            } else if (list.size() > 1) {
                //长度不为一,表中有重名(前置校验或者数据库唯一性校验失败,请查找导致重名的程序安全问题)
                throw new CommonException("用户名重名异常", 500);
            } else {
                //无相关值(list长度为零)
                throw new UsernameNotFoundException("无相关数据");
            }
        } else {
            //数据异常
            throw new CommonException("数据异常!", 500);
        }
    }

    /**
     * @Description: 获取用户权限列表
     * @Param: [userId]
     * @Return: java.util.List<org.springframework.security.core.authority.SimpleGrantedAuthority>
     * @Author: 陈建
     * @date: 2018/6/11 17:17
     */
    private List<SimpleGrantedAuthority> createAuthorities(Long userId) {
        List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
        //根据用户ID在权限关系表中查找该用户对应的所有权限;
        List<UserRoles> rolesList = userRolesMapper.findByUserId(userId);
        //将字符串权限转化成安全框架可以识别的权限对象
        for (UserRoles roles : rolesList) {
            SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(roles.getRoleName());
            simpleGrantedAuthorities.add(simpleGrantedAuthority);
        }
        return simpleGrantedAuthorities;
    }

    @Override
    public UserVO creatNewUser(UserEntity userEntity) {
        UserVO userVO = new UserVO();
        //用户密码加密
        userEntity.setPassword(new BCryptPasswordEncoder().encode(userEntity.getPassword()));
        //存储用户基本信息
        UserEntity entity = userMapper.saveAndFlush(userEntity);
        //用户赋权(设定角色)
        if (null != entity) {

            //创建权限记录实体(此处将用户权限实体化存储)
            UserRoles role = new UserRoles();
            role.setUserId(entity.getId());
            //初始创建后默认用户位DEF权限;
            role.setRoleName(SECURITY_ROLES_ENUM.DEF.getRoles());
            //保存权限关系实体
            UserRoles userRoles = userRolesMapper.saveAndFlush(role);

            //用户多权限容器
            List<String> roles = new ArrayList<>();
            roles.add(userRoles.getRoleName());
            userVO.setUserEntity(entity);
            userVO.setRoles(roles);
        }
        return userVO;
    }
}
